package com.bblocks.common.anti_reptile.spring;


import com.bblocks.common.anti_reptile.config.AntiReptileProperties;
import com.bblocks.common.anti_reptile.interceptor.ResultStrategy;
import com.bblocks.common.anti_reptile.rateLimiter.RateLimiterPlan;
import com.bblocks.common.anti_reptile.rule.RuleData;
import com.bblocks.common.anti_reptile.rule.impl.*;
import com.bblocks.common.anti_reptile.config.WebMvcConfig;
import com.bblocks.common.anti_reptile.constant.AntiReptileConsts;
import com.bblocks.common.anti_reptile.interceptor.AntiReptileInterceptor;
import com.bblocks.common.anti_reptile.interceptor.ResultStrategyDefault;
import com.bblocks.common.anti_reptile.rateLimiter.RateLimiterPlanDefault;
import com.bblocks.common.anti_reptile.rule.AntiReptileRule;
import com.bblocks.common.anti_reptile.rule.RuleActuator;
import com.bblocks.common.anti_reptile.rule.impl.RuleDataDefault;
import com.bblocks.common.anti_reptile.service.TokenService;
import com.bblocks.common.anti_reptile.service.impl.TokenServiceImplDefault;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * @author Jin
 * @since 2024/3/24
 */
//@Configuration
@EnableConfigurationProperties(AntiReptileProperties.class)
@ConditionalOnProperty(prefix = "anti.reptile", value = "enabled", havingValue = "true")
@Import({/*RedissonAutoConfig.class, */WebMvcConfig.class})
public class AntiReptileAutoConfig {


    @Bean
    @ConditionalOnProperty(prefix = "anti.reptile.ip-rule",value = "enabled", havingValue = "true", matchIfMissing = false)
    public IpRule ipRule(RateLimiterPlan rateLimiterPlan,AntiReptileProperties properties){
        return new IpRule(rateLimiterPlan,properties);
    }

    @Bean
    @ConditionalOnProperty(prefix = "anti.reptile.ua-rule",value = "enabled", havingValue = "true", matchIfMissing = false)
    public UaRule uaRule(AntiReptileProperties properties) {
        return new UaRule(properties);
    }

    @Bean
    @ConditionalOnProperty(prefix = "anti.reptile.ip-plus-rule",value = "enabled", havingValue = "true", matchIfMissing = false)
    public IpPlusRule ipPlusRule(RateLimiterPlan rateLimiterPlan,AntiReptileProperties properties,TokenService tokenService) {
        return new IpPlusRule(rateLimiterPlan, properties,tokenService);
    }

    @Bean
    @ConditionalOnProperty(prefix = "anti.reptile.user-rule",value = "enabled", havingValue = "true", matchIfMissing = false)
    public UserRule userRule(RateLimiterPlan rateLimiterPlan,AntiReptileProperties properties,TokenService tokenService) {
        return new UserRule(rateLimiterPlan,properties,tokenService);
    }


    @Bean
    public RuleActuator ruleActuator(final List<AntiReptileRule> rules){
        final List<AntiReptileRule> antiReptileRules = rules.stream()
                .sorted(Comparator.comparingInt(AntiReptileRule::getOrder)).collect(Collectors.toList());
        return new RuleActuator(antiReptileRules);
    }


    @Bean
    public AntiReptileInterceptor antiReptileInterceptor() {
        return new AntiReptileInterceptor();
    }



    /**
     *
     * 以下未默认方案，有需要可以定制
     */


    /**
     * 默认token转userId方案（就是不转！！）
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(TokenService.class)
    public TokenServiceImplDefault tokenServiceImplDefault() {
        return new TokenServiceImplDefault();
    }

    /**
     * 默认拦截后默认处理逻辑-直接返回json
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(ResultStrategy.class)
    public ResultStrategyDefault resultStrategyDefault() {
        return new ResultStrategyDefault();
    }

    /**
     * 查询规则-默认的本地内存方案未实现（默认方案就是未配置方案-直接放行）
     * @param antiReptileProperties
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(RuleData.class)
    public RuleDataDefault ruleDataDefault(AntiReptileProperties antiReptileProperties) {
        return new RuleDataDefault(antiReptileProperties);
    }


    /**
     * 默认限流方案-也未实现直接放行
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(RateLimiterPlan.class)
    public RateLimiterPlanDefault rateLimiterPlanDefault() {
        return new RateLimiterPlanDefault();
    }

}
